﻿using Azure.Core;
using DataModels.Dto;
using DataModels.Dto.WorkOrder;
using DataModels.Entities.Base;
using DataModels.Entities.House;
using DataModels.Entities.ServiceDay;
using DataModels.Entities.WorkOrder;
using DataModels.Enums.WorkOrder;
using Microsoft.VisualBasic;
using SEGIService.Service.Basic.Work;
using Services.House;
using SqlSugar;
using SqlSugar.Extensions;
using System.Runtime.Intrinsics.Arm;
using System.Threading.Tasks;
using Utils;
using static DataModels.Enums.GeneralEnum;
using static QRCoder.PayloadGenerator;

namespace Services.WorkOrder
{
    public class WorkOrderService(SqlSugarClient db, HouseService houseService, SigeWorkService sws) : BaseService(db)
    {
        protected readonly HouseService _houseService = houseService;


        /// <summary>
        /// 记录变更历史
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private Guid RecordHistory(WorkOrderTable model)
        {
            // 记录工单变更历史
            WorkOrderHistory history = new()
            {
                UUID = Guid.NewGuid(), // 为历史记录生成新的UUID
                WorkOrderUUID = model.UUID,
                OrderNo = model.OrderNo,
                HouseUUID = model.HouseUUID,
                Phone = model.Phone,
                Title = model.Title,
                Description = model.Description,
                TypeId = model.TypeId,
                Type = model.Type,
                Priority = model.Priority,
                Status = model.Status,
                ActualResolveTime = model.ActualResolveTime,
                CreateTime = model.CreateTime,
                UpdateTime = model.UpdateTime,
                CloseTime = model.CloseTime,
                RequesterId = model.RequesterId,
                ProcessorId = model.ProcessorId,
                ProjectId = model.ProjectId,
                SatisfactionScore = model.SatisfactionScore,
                SatisfactionComment = model.SatisfactionComment,
                ReasonForChange = model.ReasonForChange,
                Urgent = model.Urgent
            };

            db.Insertable(history).ExecuteCommand();
            return history.UUID;
        }

        /// <summary>
        /// 获取工单类型
        /// </summary>
        /// <returns></returns>
        public ResponseModel GetWorkOrderType(int ParentId = -1, string WhereToUse = "sige")
        {
            //更新四格工单类别
           // sws.UpdateWorkordertype();

            // 查询所有启用的工单类型
            var allTypes = db.Queryable<WorkOrderType>()
                             .Where(x => x.Status == Status.Enable)
                             .Where(x => x.WhereToUse == WhereToUse)
                             .ToList();

            // 递归构建树结构
            List<WorkOrderTypeTree> BuildTree(List<WorkOrderType> nodes, int? parentId)
            {
                return nodes
                    .Where(x => x.ParentId == parentId)
                    .Select(x => new WorkOrderTypeTree
                    {
                        Id = x.Id,
                        Name = x.Name,
                        ParentId = x.ParentId,
                        Children = BuildTree(nodes, x.Id)
                    })
                    .ToList();
            }

            // 返回树形结构
            var data = BuildTree(allTypes, ParentId == -1 ? 0 : ParentId);
            return Success(data);
        }



        /// <summary>
        /// 创建工单
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<ResponseModel> CreateWorkOrder(CreateWorkOrderInfo info)
        {
            try
            {
                var house = db.Queryable<HousingBasic>().Where(x => x.HouseId == info.HouseId).First();
                if (house == null)
                {
                    return Error("房屋不存在", 400);
                }
                WorkOrderType wot = db.Queryable<WorkOrderType>().Where(wot => wot.Id == info.TypeId).First();
                if (wot == null)
                {
                    return Error("工单类型不存在", 400);
                }
                var model = new WorkOrderTable
                {
                    TypeId = info.TypeId,
                    Type = wot.Name,
                    HouseUUID = house.UUID,
                    Phone = info.Phone,
                    Description = info.Description,
                    RequesterId = UserUUID,
                    ProjectId = info.ProjectId,
                    DoorTime = info.DoorTime
                };

                try
                {
                    //  同步四格 
                    SigeCreateWorkOrderInfoRequest bodydata = new SigeCreateWorkOrderInfoRequest()
                    {
                        main_segi_community_id = Convert.ToInt32(GetOrganIdBySIGE((Guid)info.ProjectId)), // 项目ID（真实小区ID）  ????
                        templateDifId = wot.TemplateDifId, //类型大类  工单所属的服务类型编码（服务大类）
                        busiType = wot.ServiceTypeCode, //类型小类  业务类型 busiCode

                        contactTel = info.Phone,  // 电话
                        content = info.Description,  //内容
                        houseId = house.HouseId.ToString()  //四格房屋id
                    };
                    string sigeserviceOrderId = await sws.AddWorkerInfo(bodydata);
                    if (!string.IsNullOrWhiteSpace(sigeserviceOrderId))
                    {
                        model.OrderNo = sigeserviceOrderId;
                    }
                }
                catch (Exception)
                {
                    return Error("四格工单异常", 400);
                }

                db.BeginTran();
                WorkOrderTable wo = db.Insertable(model).ExecuteReturnEntity();
                info.Urls.Select(url => new Attachment
                {
                    BusinessId = wo.UUID,
                    Url = url,
                    CreatedBy = UserUUID
                }).ToList().ForEach(a =>
                {
                    db.Insertable(a).ExecuteCommand();
                });

                db.CommitTran();
                return Success("提交成功");
            }
            catch
            {
                db.RollbackTran();
                return Error("提交失败", 400);
            }
        }


        public (Boolean, object) CheckWorkOrder(Guid WorkOrderId)
        {
            var wo = db.Queryable<WorkOrderTable>().Where(wo => wo.UUID == WorkOrderId).First();
            if (wo == null)
            {
                return (false, "未查询到工单信息");
            }
            switch (wo.Status)
            {
                case WorkOrderStatus.New:
                    break;
                case WorkOrderStatus.Assigned:
                    break;
                case WorkOrderStatus.Processing:
                    break;
                case WorkOrderStatus.WaitingForFeedback:
                    break;
                case WorkOrderStatus.Resolved:
                    return (false, $"工单：{wo.OrderNo}，{WorkOrderStatus.Resolved.GetDescription()}");
                case WorkOrderStatus.Closed:
                    return (false, $"工单：{wo.OrderNo}，{WorkOrderStatus.Closed.GetDescription()}");
                case WorkOrderStatus.Cancelled:
                    return (false, $"工单：{wo.OrderNo}，{WorkOrderStatus.Cancelled.GetDescription()}");
                default:
                    break;
            }
            return (true, wo);
        }

        /// <summary>
        /// 工单加急
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public ResponseModel UrgentWorkOrder(UrgentWorkOrder info)
        {
            var re = CheckWorkOrder(info.WorkOrderId);
            if (!re.Item1)
            {
                return Error(re.Item2.ToString());
            }

            WorkOrderTable wo = (WorkOrderTable)re.Item2;

            if (wo.Urgent == DataModels.Enums.GeneralEnum.Status.Enable)
            {
                return Error("工单已经是加急状态");
            }
            RecordHistory(wo);
            wo.Urgent = DataModels.Enums.GeneralEnum.Status.Enable;
            db.Updateable(wo).ExecuteCommand();

            return Success("已加急");
        }

        /// <summary>
        /// 取消工单
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public ResponseModel CancelledWorkOrder(discontinueWorkOrder info)
        {
            var re = CheckWorkOrder(info.WorkOrderId);
            if (!re.Item1)
            {
                return Error(re.Item2.ToString());
            }

            WorkOrderTable wo = (WorkOrderTable)re.Item2;
            wo.Status = WorkOrderStatus.Cancelled;
            wo.ReasonForChange = info.ReasonForChange;
            wo.UpdateTime = DateTime.Now;

            db.Updateable(wo).ExecuteCommand();


            //  同步四格 
            var bodydata = new
            {
                main_segi_community_id = GetOrganIdBySIGE((Guid)wo.ProjectId), //项目ID（真实小区ID）
                serviceOrderId = wo.OrderNo,
                cause = wo.ReasonForChange
            };
           sws.discontinueOrder(bodydata);


            return Success("已撤销");
        }

        /// <summary>
        /// 评价工单
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<ResponseModel> ResolvedWorkOrder(ResolvedWorkOrder info)
        {
            try
            {
             db.BeginTran();
            var re = CheckWorkOrder(info.WorkOrderId);
            if (!re.Item1)
            {
                return Error(re.Item2.ToString());
            }

            WorkOrderTable wo = (WorkOrderTable)re.Item2;

            if (wo.Status != WorkOrderStatus.WaitingForFeedback)
            {
                return Error("只能评价待评价的工单");
            }

            wo.Status = WorkOrderStatus.Resolved;
            wo.SatisfactionScore = info.SatisfactionScore;
            switch (info.SatisfactionScore)
            {
                case 4: //4 星10积分
                    AddPoint(10);
                    break;
                case 5: //5 星20积分
                    AddPoint(20);
                    break;
                default:
                    break;
            }
            wo.SatisfactionComment = info.SatisfactionComment;
            wo.UpdateTime = DateTime.Now;
            db.Updateable(wo).ExecuteCommand();
            //  同步四格 
            var bodydata = new
            {
                main_segi_community_id = GetOrganIdBySIGE((Guid)wo.ProjectId), //项目ID（真实小区ID）
                serviceOrderId = wo.OrderNo,
                evaluationValue =wo.SatisfactionScore
            };
            string sigeserviceOrderId = await sws.evaluateServiceOrder(bodydata);
            db.CommitTran();
            return Success("评价完成");
            }
            catch (Exception)
            {
                db.RollbackTran();
                throw;
            }
        }
        /// <summary>
        /// 添加积分点数
        /// </summary>
        /// <param name="point"></param>
        private void AddPoint(int point) {
            ServiceDayPoints sdp = new ServiceDayPoints
            {
                UUID=Guid.NewGuid(),
                Points=point,
                UserUUID = UserUUID,
                UpdateTime=DateTime.Now,
                UpdateUserUUID= UserUUID,
                Source= "服务评价"
            };
            db.Insertable(sdp).ExecuteCommand();
        }
        /// <summary>
        /// 获取工单列表
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<ResponseModel> GetWorkOrder(GetWorkOrderInfo info)
        {
            //同步四格工单状态
            await sws.UpdateWorkerStatic(info.Phone);
            
            List<GetWorkOrderDto> wod = db.Queryable<WorkOrderTable, Projects>((wot, p) => new object[]
            {
                JoinType.Left,wot.ProjectId == p.UUID
            })
                .Where(wot => wot.ProcessorId == UserUUID || wot.RequesterId == UserUUID)
                .WhereIF(info.ProjectId.HasValue, wot => wot.ProjectId == info.ProjectId)
                .WhereIF(info.StartTime.HasValue, wot => wot.CreateTime >= info.StartTime)
                .WhereIF(info.EndTime.HasValue, wot => wot.CreateTime <= info.EndTime)
                .WhereIF(info.Status.Count != 0, wot => info.Status.Contains(wot.Status))
                .OrderBy(wot => wot.CreateTime, OrderByType.Desc)
                .Select((wot, p) => new GetWorkOrderDto
                {
                    WorkOrderId = wot.UUID,
                    ProjectName = p.ProjectName,
                    Type = wot.Type,
                    Status = wot.Status,
                    Urgent = wot.Urgent,
                    CreateTime = wot.CreateTime
                })
                .ToList()
                ;
            List<GetWorkOrderResponse> res = [.. wod.Select(dto => new GetWorkOrderResponse
            {
                WorkOrderId = dto.WorkOrderId,
                ProjectName = dto.ProjectName,
                Type = dto.Type,
                Status = dto.Status,
                Urgent = dto.Urgent.ObjToBool(),
                CreateTime = dto.CreateTime
            })];
            return Success(res);
        }

        /// <summary>
        /// 获取工单详情历史记录
        /// </summary>
        /// <param name="workorderid"></param>
        /// <returns></returns>
        public ResponseModel GetWorkOrderHistory(Guid workorderid)
        {
            GetWorkOrderHistoryDto wot = db.Queryable<WorkOrderTable, HousingBasic, WorkOrderType>((wot, hb, wott) => new object[]
            {
                JoinType.Left,wot.HouseUUID == hb.UUID,
                JoinType.Left,wot.TypeId ==wott.Id
            })
                .LeftJoin<WorkOrderType>((wot, hb, wott, wott1) => wott.ParentId == wott1.Id)
                .Where(wot => wot.UUID == workorderid)
                .Select((wot, hb, wott, wott1) => new GetWorkOrderHistoryDto
                {
                    OrderNo = wot.OrderNo,
                    PropertiesUUID = hb.PropertiesUUID,
                    Type = wott1.Name + "-" + wot.Type,
                    Phone = wot.Phone,
                    CreateTime = wot.CreateTime,
                    Description = wot.Description,
                    SatisfactionScore = wot.SatisfactionScore,
                    Status = wot.Status,
                    Urgent = wot.Urgent
                }).First();
            if (wot == null)
            {
                return Error("工单不存在");
            }
            var cuser = db.Queryable<Customer>().Where(c => c.Tel1 == wot.Phone).First();
            if (cuser == null)
            {
                return Error("用户不存在");
            }
            var pp = db.Queryable<CustomerHouseRelation>().Where(x => x.CustId == cuser.CustId && x.RelType == "1").First();

            //Properties pp = db.Queryable<Properties>().Where(pp => pp.UUID == Guid.Parse(wot.PropertiesUUID)).First();
            List<string> urls = db.Queryable<Attachment>().Where(atc => atc.BusinessId == workorderid).Select(atc => atc.Url).ToList();
            List<WorkOrderHistory> woth = db.Queryable<WorkOrderHistory>().Where(wot => wot.WorkOrderUUID == workorderid).OrderBy(wot => wot.OrderNo, OrderByType.Asc).ToList();

            GetWorkOrderHistoryResponse res = new()
            {
                OrderNo = wot.OrderNo,
                PropertiesUUID = wot.PropertiesUUID,
                Type = wot.Type,
                Phone = wot.Phone,
                Urgent = wot.Urgent == DataModels.Enums.GeneralEnum.Status.Enable,
                CreateTime = wot.CreateTime,
                Description = wot.Description,
                SatisfactionScore = wot.SatisfactionScore,
                Status = wot.Status.GetDescription(),
                FullAddress = pp.ResourceName,
                Urls = urls,
                Progress = [.. woth.Select(dt => new WorkOrderHistoryProgress
                {
                    Status = dt.Status.GetDescription(),
                    OrderNo = dt.OrderNo,
                    UpdateTime = dt.CreateTime,
                    ReasonForChange=dt.ReasonForChange,
                    Urgent = dt.Urgent == DataModels.Enums.GeneralEnum.Status.Enable
                })]
            };

            return Success(res);
        }
    }
}
